package cn.yeziji.utils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author gzkemays
 * @since 2021/11/18 19:14
 */
public class StrUtils {
  private static final String HTTP = "http";
  private static final String HTTPS = "https";
  private static final String WWW = "www.";

  /**
   * 是否为 web
   *
   * @param url 地址
   * @return 判断结果
   */
  public static boolean isWeb(String url) {
    return (url.startsWith(HTTP) || url.startsWith(HTTPS) || url.startsWith(WWW));
  }

  /**
   * list 转字符串
   *
   * @param list 列表
   * @param separator 分割符
   * @param <T> 转化类型
   * @return 字符串结果
   */
  public static <T> String listToStr(List<T> list, char separator) {
    StringJoiner sj = new StringJoiner(",");
    for (Object o : list) {
      sj.add(String.valueOf(o));
    }
    return sj.toString();
  }

  private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");

  /**
   * 将 str 首字母转换为大写
   *
   * @param str 字符串
   * @return 以大写为开头的字符串
   */
  public static String getFirstUpperStr(String str) {
    String firstStr = str.toLowerCase().substring(0, 1);
    return str.replace(firstStr, firstStr.toUpperCase());
  }

  /**
   * 清除 null 数据
   *
   * @param obj 需要清除的对象
   * @return 无 null 对象
   */
  public static String clearNull(Object obj) {
    Class<?> clazz = obj.getClass();
    StringJoiner sj = new StringJoiner(", ", clazz.getSimpleName() + "={", "}");
    try {
      Field[] fields = clazz.getDeclaredFields();
      for (Field field : fields) {
        field.setAccessible(true);
        String fieldName = field.getName();
        PropertyDescriptor descriptor =
                new PropertyDescriptor(
                        field.getName(),
                        clazz,
                        "get" + getFirstUpperStr(fieldName),
                        "set" + getFirstUpperStr(fieldName));
        Method readMethod = descriptor.getReadMethod();
        Object invoke = readMethod.invoke(obj);
        if (invoke != null) {
          sj.add(fieldName + "=" + invoke);
        }
      }
      return sj.toString();
    } catch (IllegalAccessException | IntrospectionException | InvocationTargetException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 驼峰转下划线
   *
   * <p>aBc -> a_bc
   *
   * @param str 驼峰字符串
   * @return 转为下划线
   */
  public static String humpToLine(String str) {
    Matcher matcher = HUMP_PATTERN.matcher(str);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
      // 匹配替换字符
      matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
    }
    // 将最后一次匹配后面的字串进行追加
    matcher.appendTail(sb);
    return sb.toString();
  }

  /**
   * 返回 base64 编码字符串
   *
   * @param str 原字符串
   * @return base64 编码字符串
   */
  public static String getBase64Str(String str) {
    return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
  }

  /**
   * 解码 base64
   *
   * @param str base64 编码文本
   * @return 返回解码内容
   */
  public static String getStrByBase64(String str) {
    return new String(Base64.getDecoder().decode(str.getBytes(StandardCharsets.UTF_8)));
  }
}
